#include "request_handler_base.h"

#include "result_processor.h"

RequestHandler::RequestHandler(QNetworkAccessManager *manager)
    : manager_(manager)
{
    connect(manager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(ReplyFinished(QNetworkReply*)));
}

RequestHandler::RequestHandler(QNetworkAccessManager *manager, RequestMethod request)
    : manager_(manager), request_(request) {
    connect(manager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(ReplyFinished(QNetworkReply*)));
}

RequestHandler::~RequestHandler() {

}

void RequestHandler::SetRequestMethod(RequestMethod request) {
    request_ = request;
}

void RequestHandler::IssueRequest() {
    // Assemble the request URL
    QString uri;
    uri.append(kServerURL);
    uri.append(kGetString);
    uri.append("?");
    uri.append(kFormatString);
    uri.append("=");
    uri.append(request_.format);
    uri.append("&");
    uri.append(kMethodString);
    uri.append("=");
    uri.append(request_.method);
    if (request_.params.count() > 0) {
        uri.append("&");

        for (int i = 0; i < request_.params.count() - 1; ++i) {
            RequestMethod::param &p = request_.params[i];
            uri.append(p.name);
            uri.append("=");
            uri.append(p.value.toString());
            uri.append("&");
        }

        // the last param pair
        RequestMethod::param &p = request_.params[request_.params.count() - 1];
        uri.append(p.name);
        uri.append("=");
        uri.append(p.value.toString());
    }
    qDebug() << "RequestHandlerBase::IssueRequest(): uri = " << uri;
    // Issue the actual network request
    reply_ = manager_->get(QNetworkRequest(QUrl(uri)));
}

void RequestHandler::IssueRequest(QString request) {
  qDebug() << "RequestHandlerBase::IssueRequest(): uri = " << request;
  reply_ = manager_->get(QNetworkRequest(QUrl(request)));
}

void RequestHandler::IssueRequest(RequestMethod request) {
  request_ = request;
  if (request.rawRequest.length() == 0) {
    IssueRequest();
  } else {
    IssueRequest(request.rawRequest);
  }
}

void RequestHandler::Cancel() {
  if (reply_) {
    reply_->abort();
  }
}

void RequestHandler::ReplyFinished(QNetworkReply *reply) {
    if (reply == reply_) {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray bytes = reply->readAll();
            QDomDocument doc;
            bool isDom = doc.setContent(bytes);
            if (isDom) {
              QDomElement e = doc.documentElement();
              request_.processor->ProcessResult(request_, e);
            } else {
              qDebug() << "Raw data occured";
              request_.processor->ProcessRawResult(bytes);
            }
        } else {
            emit Error(reply);
        }
        reply->deleteLater();
    }
}
